#!/usr/bin/perl -w
#Purpose: make RRTs that match the %GC of the original sequence
#uses codon usage data counted from sequences binned by %GC content in the 3rd codon position (%GC3)
#this version makes 1 RRT of ORFeome

$dnafile = $ARGV[0];#fasta formatted DNA file (sequence all on 1 line)
open(DNA,$dnafile) or die("couldn't open dna file\n");

$CIGC3 = $ARGV[1];#output from CodonCountGC3bins.pl
open(CIFILE,$CIGC3) or die("couldn't open ci file\n");

$output = $ARGV[2];#stats for how close RRTs were to original %GC
open(OUTPUT,">$output") or die ("couldn't open statsfile\n");

$output2 = $ARGV[3];#RRT sequences
open(OUTPUT2,">$output2") or die ("couldn't open sequencefile\n");

$SeqCutoff = 20;#use CI bins with at least this number of sequences
$cutoff = 1;#try to make RRTs within +/- this number of original %GC content
$trials = 5;#try a different codon usage bin if don't get a good RRT within this number of attempts using current bin
$totaltrials = 50;#increase cutoff by 1 if don't get a good RRT within this many total trials 

$SeqCounts = <CIFILE>;chomp $SeqCounts;@SeqCounts = split("\t",$SeqCounts);#first line indicates number of sequences per bin
$Averages = <CIFILE>;chomp $Averages;@Averages = split("\t",$Averages);#second line indicates average %GC3 for each bin

$CIbins = 0;#how many CI bins will be used
@CIAve = ();#average %GC3 for each bin used
foreach $seqcount (@SeqCounts){$ave = shift @Averages;if ($seqcount > $SeqCutoff or $seqcount == $SeqCutoff){++$CIbins;push(@CIAve,$ave);}}

#these will be used to indicate the number of codon choices (to set upper limit on random number later)
@Fcounts = ();until (scalar @Fcounts == $CIbins){push (@Fcounts,"0")};
@Lcounts = ();until (scalar @Lcounts == $CIbins){push (@Lcounts,"0")};
@Icounts = ();until (scalar @Icounts == $CIbins){push (@Icounts,"0")};
@Mcounts = ();until (scalar @Mcounts == $CIbins){push (@Mcounts,"0")};
@Vcounts = ();until (scalar @Vcounts == $CIbins){push (@Vcounts,"0")};
@Scounts = ();until (scalar @Scounts == $CIbins){push (@Scounts,"0")};
@Pcounts = ();until (scalar @Pcounts == $CIbins){push (@Pcounts,"0")};
@Tcounts = ();until (scalar @Tcounts == $CIbins){push (@Tcounts,"0")};
@Acounts = ();until (scalar @Acounts == $CIbins){push (@Acounts,"0")};
@Ycounts = ();until (scalar @Ycounts == $CIbins){push (@Ycounts,"0")};
@Zcounts = ();until (scalar @Zcounts == $CIbins){push (@Zcounts,"0")};
@Hcounts = ();until (scalar @Hcounts == $CIbins){push (@Hcounts,"0")};
@Qcounts = ();until (scalar @Qcounts == $CIbins){push (@Qcounts,"0")};
@Ncounts = ();until (scalar @Ncounts == $CIbins){push (@Ncounts,"0")};
@Kcounts = ();until (scalar @Kcounts == $CIbins){push (@Kcounts,"0")};
@Dcounts = ();until (scalar @Dcounts == $CIbins){push (@Dcounts,"0")};
@Ecounts = ();until (scalar @Ecounts == $CIbins){push (@Ecounts,"0")};
@Ccounts = ();until (scalar @Ccounts == $CIbins){push (@Ccounts,"0")};
@Wcounts = ();until (scalar @Wcounts == $CIbins){push (@Wcounts,"0")};
@Rcounts = ();until (scalar @Rcounts == $CIbins){push (@Rcounts,"0")};
@Gcounts = ();until (scalar @Gcounts == $CIbins){push (@Gcounts,"0")};

#these will become arrays of codons for each AA (Z is for stop):
@F = ();@L = ();@I = ();@M = ();@V = ();@S = ();@P = ();@T = ();@A = ();@Y = ();@Z = ();@H = ();@Q = ();@N = ();@K = ();@D = ();@E = ();@C = ();@W = ();@R = ();@G = ();

@CodonCounts = ();#number of each codon found in each bin

#collect codon usage data from usable bins (with sequence data):
while ($CIline = <CIFILE>){
	chomp $CIline;
	@CIline = split("\t",$CIline);
	$binnum = 0;
	@CI = ();
	$codon = shift @CIline;push(@CI,$codon);
	foreach $bin (@CIline){
		$count = $SeqCounts[$binnum];#print "bin $binnum seq $count\n";
		if ($count > $SeqCutoff or $count == $SeqCutoff){push(@CI,$bin);}
		++$binnum;
	}
	push(@CodonCounts, [@CI]);
}#while collecting data from CI files

close CIFILE;

$currentbin = 1;#start with 1 bc 0 = codon
until ($currentbin == $CIbins + 1){
	
	$codonnum = 0;
	until ($codonnum == 64){#until last codon: get codon counts for current CI bin
		$codon = $CodonCounts[$codonnum][0];
		$number = $CodonCounts[$codonnum][$currentbin];
		#get counts for each codon for current CI bin:
		if ($codon eq "TTT"){$TTT = $number;}elsif ($codon eq "TTC"){$TTC = $number;}elsif ($codon eq "TTA"){$TTA = $number;}elsif ($codon eq "TTG"){$TTG = $number;}elsif ($codon eq "CTT"){$CTT = $number;}elsif ($codon eq "CTC"){$CTC = $number;}elsif ($codon eq "CTA"){$CTA = $number;}elsif ($codon eq "CTG"){$CTG = $number;}elsif ($codon eq "ATT"){$ATT = $number;}elsif ($codon eq "ATC"){$ATC = $number;}elsif ($codon eq "ATA"){$ATA = $number;}elsif ($codon eq "ATG"){$ATG = $number;}elsif ($codon eq "GTT"){$GTT = $number;}elsif ($codon eq "GTC"){$GTC = $number;}elsif ($codon eq "GTA"){$GTA = $number;}elsif ($codon eq "GTG"){$GTG = $number;}elsif ($codon eq "TCT"){$TCT = $number;}elsif ($codon eq "TCC"){$TCC = $number;}elsif ($codon eq "TCA"){$TCA = $number;}elsif ($codon eq "TCG"){$TCG = $number;}elsif ($codon eq "AGT"){$AGT = $number;}elsif ($codon eq "AGC"){$AGC = $number;}elsif ($codon eq "CCT"){$CCT = $number;}elsif ($codon eq "CCC"){$CCC = $number;}elsif ($codon eq "CCA"){$CCA = $number;}elsif ($codon eq "CCG"){$CCG = $number;}elsif ($codon eq "ACT"){$ACT = $number;}elsif ($codon eq "ACC"){$ACC = $number;}elsif ($codon eq "ACA"){$ACA = $number;}elsif ($codon eq "ACG"){$ACG = $number;}elsif ($codon eq "GCT"){$GCT = $number;}elsif ($codon eq "GCC"){$GCC = $number;}elsif ($codon eq "GCA"){$GCA = $number;}elsif ($codon eq "GCG"){$GCG = $number;}elsif ($codon eq "TAT"){$TAT = $number;}elsif ($codon eq "TAC"){$TAC = $number;}elsif ($codon eq "TAA"){$TAA = $number;}elsif ($codon eq "TAG"){$TAG = $number;}elsif ($codon eq "CAT"){$CAT = $number;}elsif ($codon eq "CAC"){$CAC = $number;}elsif ($codon eq "CAA"){$CAA = $number;}elsif ($codon eq "CAG"){$CAG = $number;}elsif ($codon eq "AAT"){$AAT = $number;}elsif ($codon eq "AAC"){$AAC = $number;}elsif ($codon eq "AAA"){$AAA = $number;}elsif ($codon eq "AAG"){$AAG = $number;}elsif ($codon eq "GAT"){$GAT = $number;}elsif ($codon eq "GAC"){$GAC = $number;}elsif ($codon eq "GAA"){$GAA = $number;}elsif ($codon eq "GAG"){$GAG = $number;}elsif ($codon eq "TGT"){$TGT = $number;}elsif ($codon eq "TGC"){$TGC = $number;}elsif ($codon eq "TGA"){$TGA = $number;}elsif ($codon eq "TGG"){$TGG = $number;}elsif ($codon eq "CGT"){$CGT = $number;}elsif ($codon eq "CGC"){$CGC = $number;}elsif ($codon eq "CGA"){$CGA = $number;}elsif ($codon eq "CGG"){$CGG = $number;}elsif ($codon eq "AGA"){$AGA = $number;}elsif ($codon eq "AGG"){$AGG = $number;}elsif ($codon eq "GGT"){$GGT = $number;}elsif ($codon eq "GGC"){$GGC = $number;}elsif ($codon eq "GGA"){$GGA = $number;}elsif ($codon eq "GGG"){$GGG = $number;}
		++$codonnum;
	}#until last codon: get codon counts for current CI bin
	
	#count number of codons for each AA: used later for setting possible size of random number
	$Fcounts[$currentbin - 1] = $Fcounts[$currentbin - 1] + $TTT;
	$Fcounts[$currentbin - 1] = $Fcounts[$currentbin - 1] + $TTC;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $TTA;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $TTG;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $CTT;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $CTC;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $CTA;
	$Lcounts[$currentbin - 1] = $Lcounts[$currentbin - 1] + $CTG;
	$Icounts[$currentbin - 1] = $Icounts[$currentbin - 1] + $ATT;
	$Icounts[$currentbin - 1] = $Icounts[$currentbin - 1] + $ATC;
	$Icounts[$currentbin - 1] = $Icounts[$currentbin - 1] + $ATA;
	$Mcounts[$currentbin - 1] = $Mcounts[$currentbin - 1] + $ATG;
	$Vcounts[$currentbin - 1] = $Vcounts[$currentbin - 1] + $GTT;
	$Vcounts[$currentbin - 1] = $Vcounts[$currentbin - 1] + $GTC;
	$Vcounts[$currentbin - 1] = $Vcounts[$currentbin - 1] + $GTA;
	$Vcounts[$currentbin - 1] = $Vcounts[$currentbin - 1] + $GTG;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $TCT;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $TCC;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $TCA;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $TCG;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $AGT;
	$Scounts[$currentbin - 1] = $Scounts[$currentbin - 1] + $AGC;
	$Pcounts[$currentbin - 1] = $Pcounts[$currentbin - 1] + $CCT;
	$Pcounts[$currentbin - 1] = $Pcounts[$currentbin - 1] + $CCC;
	$Pcounts[$currentbin - 1] = $Pcounts[$currentbin - 1] + $CCA;
	$Pcounts[$currentbin - 1] = $Pcounts[$currentbin - 1] + $CCG;
	$Tcounts[$currentbin - 1] = $Tcounts[$currentbin - 1] + $ACT;
	$Tcounts[$currentbin - 1] = $Tcounts[$currentbin - 1] + $ACC;
	$Tcounts[$currentbin - 1] = $Tcounts[$currentbin - 1] + $ACA;
	$Tcounts[$currentbin - 1] = $Tcounts[$currentbin - 1] + $ACG;
	$Acounts[$currentbin - 1] = $Acounts[$currentbin - 1] + $GCT;
	$Acounts[$currentbin - 1] = $Acounts[$currentbin - 1] + $GCC;
	$Acounts[$currentbin - 1] = $Acounts[$currentbin - 1] + $GCA;
	$Acounts[$currentbin - 1] = $Acounts[$currentbin - 1] + $GCG;
	$Ycounts[$currentbin - 1] = $Ycounts[$currentbin - 1] + $TAT;
	$Ycounts[$currentbin - 1] = $Ycounts[$currentbin - 1] + $TAC;
	$Zcounts[$currentbin - 1] = $Zcounts[$currentbin - 1] + $TAA;
	$Zcounts[$currentbin - 1] = $Zcounts[$currentbin - 1] + $TAG;
	$Hcounts[$currentbin - 1] = $Hcounts[$currentbin - 1] + $CAT;
	$Hcounts[$currentbin - 1] = $Hcounts[$currentbin - 1] + $CAC;
	$Qcounts[$currentbin - 1] = $Qcounts[$currentbin - 1] + $CAA;
	$Qcounts[$currentbin - 1] = $Qcounts[$currentbin - 1] + $CAG;
	$Ncounts[$currentbin - 1] = $Ncounts[$currentbin - 1] + $AAT;
	$Ncounts[$currentbin - 1] = $Ncounts[$currentbin - 1] + $AAC;
	$Kcounts[$currentbin - 1] = $Kcounts[$currentbin - 1] + $AAA;
	$Kcounts[$currentbin - 1] = $Kcounts[$currentbin - 1] + $AAG;
	$Dcounts[$currentbin - 1] = $Dcounts[$currentbin - 1] + $GAT;
	$Dcounts[$currentbin - 1] = $Dcounts[$currentbin - 1] + $GAC;
	$Ecounts[$currentbin - 1] = $Ecounts[$currentbin - 1] + $GAA;
	$Ecounts[$currentbin - 1] = $Ecounts[$currentbin - 1] + $GAG;
	$Ccounts[$currentbin - 1] = $Ccounts[$currentbin - 1] + $TGT;
	$Ccounts[$currentbin - 1] = $Ccounts[$currentbin - 1] + $TGC;
	$Zcounts[$currentbin - 1] = $Zcounts[$currentbin - 1] + $TGA;
	$Wcounts[$currentbin - 1] = $Wcounts[$currentbin - 1] + $TGG;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $CGT;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $CGC;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $CGA;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $CGG;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $AGA;
	$Rcounts[$currentbin - 1] = $Rcounts[$currentbin - 1] + $AGG;
	$Gcounts[$currentbin - 1] = $Gcounts[$currentbin - 1] + $GGT;
	$Gcounts[$currentbin - 1] = $Gcounts[$currentbin - 1] + $GGC;
	$Gcounts[$currentbin - 1] = $Gcounts[$currentbin - 1] + $GGA;
	$Gcounts[$currentbin - 1] = $Gcounts[$currentbin - 1] + $GGG;
	
	#arrays of synonymous codons for each AA, for current bin: to be added to 2D array
	@Fgenerand = ();@Lgenerand = ();@Igenerand = ();@Mgenerand = ();@Vgenerand = ();@Sgenerand = ();@Pgenerand = ();@Tgenerand = ();@Agenerand = ();@Ygenerand = ();@Zgenerand = ();@Hgenerand = ();@Qgenerand = ();@Ngenerand = ();@Kgenerand = ();@Dgenerand = ();@Egenerand = ();@Cgenerand = ();@Wgenerand = ();@Rgenerand = ();@Ggenerand = ();
	
	#add synonymous codons to arrays
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TTT; ++$randomcounter) {push(@Fgenerand,'TTT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TTC; ++$randomcounter) {push(@Fgenerand,'TTC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TTA; ++$randomcounter) {push(@Lgenerand,'TTA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TTG; ++$randomcounter) {push(@Lgenerand,'TTG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CTT; ++$randomcounter) {push(@Lgenerand,'CTT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CTC; ++$randomcounter) {push(@Lgenerand,'CTC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CTA; ++$randomcounter) {push(@Lgenerand,'CTA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CTG; ++$randomcounter) {push(@Lgenerand,'CTG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ATT; ++$randomcounter) {push(@Igenerand,'ATT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ATC; ++$randomcounter) {push(@Igenerand,'ATC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ATA; ++$randomcounter) {push(@Igenerand,'ATA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ATG; ++$randomcounter) {push(@Mgenerand,'ATG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GTT; ++$randomcounter) {push(@Vgenerand,'GTT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GTC; ++$randomcounter) {push(@Vgenerand,'GTC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GTA; ++$randomcounter) {push(@Vgenerand,'GTA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GTG; ++$randomcounter) {push(@Vgenerand,'GTG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TCT; ++$randomcounter) {push(@Sgenerand,'TCT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TCC; ++$randomcounter) {push(@Sgenerand,'TCC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TCA; ++$randomcounter) {push(@Sgenerand,'TCA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TCG; ++$randomcounter) {push(@Sgenerand,'TCG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AGT; ++$randomcounter) {push(@Sgenerand,'AGT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AGC; ++$randomcounter) {push(@Sgenerand,'AGC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CCT; ++$randomcounter) {push(@Pgenerand,'CCT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CCC; ++$randomcounter) {push(@Pgenerand,'CCC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CCA; ++$randomcounter) {push(@Pgenerand,'CCA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CCG; ++$randomcounter) {push(@Pgenerand,'CCG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ACT; ++$randomcounter) {push(@Tgenerand,'ACT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ACC; ++$randomcounter) {push(@Tgenerand,'ACC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ACA; ++$randomcounter) {push(@Tgenerand,'ACA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $ACG; ++$randomcounter) {push(@Tgenerand,'ACG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GCT; ++$randomcounter) {push(@Agenerand,'GCT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GCC; ++$randomcounter) {push(@Agenerand,'GCC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GCA; ++$randomcounter) {push(@Agenerand,'GCA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GCG; ++$randomcounter) {push(@Agenerand,'GCG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TAT; ++$randomcounter) {push(@Ygenerand,'TAT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TAC; ++$randomcounter) {push(@Ygenerand,'TAC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TAA; ++$randomcounter) {push(@Zgenerand,'TAA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TAG; ++$randomcounter) {push(@Zgenerand,'TAG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CAT; ++$randomcounter) {push(@Hgenerand,'CAT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CAC; ++$randomcounter) {push(@Hgenerand,'CAC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CAA; ++$randomcounter) {push(@Qgenerand,'CAA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CAG; ++$randomcounter) {push(@Qgenerand,'CAG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AAT; ++$randomcounter) {push(@Ngenerand,'AAT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AAC; ++$randomcounter) {push(@Ngenerand,'AAC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AAA; ++$randomcounter) {push(@Kgenerand,'AAA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AAG; ++$randomcounter) {push(@Kgenerand,'AAG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GAT; ++$randomcounter) {push(@Dgenerand,'GAT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GAC; ++$randomcounter) {push(@Dgenerand,'GAC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GAA; ++$randomcounter) {push(@Egenerand,'GAA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GAG; ++$randomcounter) {push(@Egenerand,'GAG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TGT; ++$randomcounter) {push(@Cgenerand,'TGT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TGC; ++$randomcounter) {push(@Cgenerand,'TGC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TGA; ++$randomcounter) {push(@Zgenerand,'TGA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $TGG; ++$randomcounter) {push(@Wgenerand,'TGG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CGT; ++$randomcounter) {push(@Rgenerand,'CGT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CGC; ++$randomcounter) {push(@Rgenerand,'CGC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CGA; ++$randomcounter) {push(@Rgenerand,'CGA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $CGG; ++$randomcounter) {push(@Rgenerand,'CGG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AGA; ++$randomcounter) {push(@Rgenerand,'AGA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $AGG; ++$randomcounter) {push(@Rgenerand,'AGG');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GGT; ++$randomcounter) {push(@Ggenerand,'GGT');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GGC; ++$randomcounter) {push(@Ggenerand,'GGC');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GGA; ++$randomcounter) {push(@Ggenerand,'GGA');}
	$randomcounter = 0; for ($randomcounter = 0; $randomcounter < $GGG; ++$randomcounter) {push(@Ggenerand,'GGG');}
	
	#add synonymous codon arrays for current bin to 2D arrays for each AA:
	push @F,[@Fgenerand];
	push @L,[@Lgenerand];
	push @I,[@Igenerand];
	push @M,[@Mgenerand];
	push @V,[@Vgenerand];
	push @S,[@Sgenerand];
	push @P,[@Pgenerand];
	push @T,[@Tgenerand];
	push @A,[@Agenerand];
	push @Y,[@Ygenerand];
	push @Z,[@Zgenerand];
	push @H,[@Hgenerand];
	push @Q,[@Qgenerand];
	push @N,[@Ngenerand];
	push @K,[@Kgenerand];
	push @D,[@Dgenerand];
	push @E,[@Egenerand];
	push @C,[@Cgenerand];
	push @W,[@Wgenerand];
	push @R,[@Rgenerand];
	push @G,[@Ggenerand];
		
	++$currentbin;
	
}#until last bin

$sequences = 0;#count all sequences
$badgene = 0;#count "bad" sequences: length not multiple of 3, or contain characters other than ATGC


srand(time|$$);

while ($dnaline = <DNA>){
	if ($dnaline =~ ">"){#collect header & sequence
		$header = $dnaline;
		chomp $header;
		++$sequences;
		#print $sequences,"\n";
		$dnaseq = <DNA>;
		chomp $dnaseq;
		$dnalength = length $dnaseq;
		$codons = $dnalength/3;
		$otherstuff = $dnaseq;
		$otherstuff =~ s/A//g;$otherstuff =~ s/T//g;$otherstuff =~ s/G//g;$otherstuff =~ s/C//g;
		$lengthstuff = length $otherstuff;#characters other than ATGC ("N", etc)
		
		if ($codons == int($codons) and $lengthstuff == 0){#if length is a multiple of 3 no weird bases
			$totalattempts = 0;#total RRTs checked
			$attempts = 0;#RRTs made with current codon usage bin
			$seqcutoff = $cutoff;#acceptable % dif bewteen RRT and original seq
			$matched = 0;#RRTs within specified %GC range
			
			#get overall %GC of current sequence:
			$GCseq = $dnaseq;
			$GCseq =~ s/A//g;$GCseq =~ s/T//g;
			$GC = length $GCseq;
			$perGC = 100*($GC/$dnalength);
			
			#count GC at last base of each codon:
			$GC3 = 0;
			$basenum = 2;#start at last base of 2st codon
			until ($basenum > $dnalength){
				$base3 = substr($dnaseq,$basenum,1);
				if ($base3 eq "G" or $base3 eq "C"){++$GC3;}
				$basenum = $basenum + 3;
			}
	
			$perGC3 = 100*($GC3/$codons);#%GC at 3rd codon pos
							
			print OUTPUT  "$header\t$dnalength\t$perGC\t$perGC3\t";
			#print "$header\t$dnalength\t$perGC\n";
			
			#find codon usage bin with average %GC3 closest to %GC3 of current sequence:
			my $mindif;
			$pos = 0;
			foreach $ave (@CIAve){#find codon usage data closest to %GC of current seq
				$dif = $perGC3 - $ave;
				$absdif = ($dif**2)**0.5;#abs value different between %GC of current seq & midpoint of codon usage data
				if (!defined($mindif) || $absdif < $mindif){$mindif = $absdif;$CIbinnum = $pos;}
				++$pos;
			}#foreach set of codon data, find nearest to current seq
							
			print OUTPUT  "CI: $CIbinnum";
			
			until ($matched > 0){#until make a "good" RRT
				@curRRT = ();
				$cdnstart = 0;#first base of codon
				until ($cdnstart + 3 > $dnalength){#until last codon
				
					#take codon and pick RRT synonymous codon:
					$codon = substr($dnaseq,$cdnstart,3);
					
					if ($codon eq "TTT"){$random = int(rand($Fcounts[$CIbinnum]));$rrtcodon = $F[$CIbinnum][$random];}
					elsif ($codon eq "TTC"){$random = int(rand($Fcounts[$CIbinnum]));$rrtcodon = $F[$CIbinnum][$random];}
					elsif ($codon eq "TTA"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "TTG"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "CTT"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "CTC"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "CTA"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "CTG"){$random = int(rand($Lcounts[$CIbinnum]));$rrtcodon = $L[$CIbinnum][$random];}
					elsif ($codon eq "ATT"){$random = int(rand($Icounts[$CIbinnum]));$rrtcodon = $I[$CIbinnum][$random];}
					elsif ($codon eq "ATC"){$random = int(rand($Icounts[$CIbinnum]));$rrtcodon = $I[$CIbinnum][$random];}
					elsif ($codon eq "ATA"){$random = int(rand($Icounts[$CIbinnum]));$rrtcodon = $I[$CIbinnum][$random];}
					elsif ($codon eq "ATG"){$random = int(rand($Mcounts[$CIbinnum]));$rrtcodon = $M[$CIbinnum][$random];}
					elsif ($codon eq "GTT"){$random = int(rand($Vcounts[$CIbinnum]));$rrtcodon = $V[$CIbinnum][$random];}
					elsif ($codon eq "GTC"){$random = int(rand($Vcounts[$CIbinnum]));$rrtcodon = $V[$CIbinnum][$random];}
					elsif ($codon eq "GTA"){$random = int(rand($Vcounts[$CIbinnum]));$rrtcodon = $V[$CIbinnum][$random];}
					elsif ($codon eq "GTG"){$random = int(rand($Vcounts[$CIbinnum]));$rrtcodon = $V[$CIbinnum][$random];}
					elsif ($codon eq "TCT"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "TCC"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "TCA"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "TCG"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "AGT"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "AGC"){$random = int(rand($Scounts[$CIbinnum]));$rrtcodon = $S[$CIbinnum][$random];}
					elsif ($codon eq "CCT"){$random = int(rand($Pcounts[$CIbinnum]));$rrtcodon = $P[$CIbinnum][$random];}
					elsif ($codon eq "CCC"){$random = int(rand($Pcounts[$CIbinnum]));$rrtcodon = $P[$CIbinnum][$random];}
					elsif ($codon eq "CCA"){$random = int(rand($Pcounts[$CIbinnum]));$rrtcodon = $P[$CIbinnum][$random];}
					elsif ($codon eq "CCG"){$random = int(rand($Pcounts[$CIbinnum]));$rrtcodon = $P[$CIbinnum][$random];}
					elsif ($codon eq "ACT"){$random = int(rand($Tcounts[$CIbinnum]));$rrtcodon = $T[$CIbinnum][$random];}
					elsif ($codon eq "ACC"){$random = int(rand($Tcounts[$CIbinnum]));$rrtcodon = $T[$CIbinnum][$random];}
					elsif ($codon eq "ACA"){$random = int(rand($Tcounts[$CIbinnum]));$rrtcodon = $T[$CIbinnum][$random];}
					elsif ($codon eq "ACG"){$random = int(rand($Tcounts[$CIbinnum]));$rrtcodon = $T[$CIbinnum][$random];}
					elsif ($codon eq "GCT"){$random = int(rand($Acounts[$CIbinnum]));$rrtcodon = $A[$CIbinnum][$random];}
					elsif ($codon eq "GCC"){$random = int(rand($Acounts[$CIbinnum]));$rrtcodon = $A[$CIbinnum][$random];}
					elsif ($codon eq "GCA"){$random = int(rand($Acounts[$CIbinnum]));$rrtcodon = $A[$CIbinnum][$random];}
					elsif ($codon eq "GCG"){$random = int(rand($Acounts[$CIbinnum]));$rrtcodon = $A[$CIbinnum][$random];}
					elsif ($codon eq "TAT"){$random = int(rand($Ycounts[$CIbinnum]));$rrtcodon = $Y[$CIbinnum][$random];}
					elsif ($codon eq "TAC"){$random = int(rand($Ycounts[$CIbinnum]));$rrtcodon = $Y[$CIbinnum][$random];}
					elsif ($codon eq "TAA"){$random = int(rand($Zcounts[$CIbinnum]));$rrtcodon = $Z[$CIbinnum][$random];}
					elsif ($codon eq "TAG"){$random = int(rand($Zcounts[$CIbinnum]));$rrtcodon = $Z[$CIbinnum][$random];}
					elsif ($codon eq "CAT"){$random = int(rand($Hcounts[$CIbinnum]));$rrtcodon = $H[$CIbinnum][$random];}
					elsif ($codon eq "CAC"){$random = int(rand($Hcounts[$CIbinnum]));$rrtcodon = $H[$CIbinnum][$random];}
					elsif ($codon eq "CAA"){$random = int(rand($Qcounts[$CIbinnum]));$rrtcodon = $Q[$CIbinnum][$random];}
					elsif ($codon eq "CAG"){$random = int(rand($Qcounts[$CIbinnum]));$rrtcodon = $Q[$CIbinnum][$random];}
					elsif ($codon eq "AAT"){$random = int(rand($Ncounts[$CIbinnum]));$rrtcodon = $N[$CIbinnum][$random];}
					elsif ($codon eq "AAC"){$random = int(rand($Ncounts[$CIbinnum]));$rrtcodon = $N[$CIbinnum][$random];}
					elsif ($codon eq "AAA"){$random = int(rand($Kcounts[$CIbinnum]));$rrtcodon = $K[$CIbinnum][$random];}
					elsif ($codon eq "AAG"){$random = int(rand($Kcounts[$CIbinnum]));$rrtcodon = $K[$CIbinnum][$random];}
					elsif ($codon eq "GAT"){$random = int(rand($Dcounts[$CIbinnum]));$rrtcodon = $D[$CIbinnum][$random];}
					elsif ($codon eq "GAC"){$random = int(rand($Dcounts[$CIbinnum]));$rrtcodon = $D[$CIbinnum][$random];}
					elsif ($codon eq "GAA"){$random = int(rand($Ecounts[$CIbinnum]));$rrtcodon = $E[$CIbinnum][$random];}
					elsif ($codon eq "GAG"){$random = int(rand($Ecounts[$CIbinnum]));$rrtcodon = $E[$CIbinnum][$random];}
					elsif ($codon eq "TGT"){$random = int(rand($Ccounts[$CIbinnum]));$rrtcodon = $C[$CIbinnum][$random];}
					elsif ($codon eq "TGC"){$random = int(rand($Ccounts[$CIbinnum]));$rrtcodon = $C[$CIbinnum][$random];}
					elsif ($codon eq "TGA"){$random = int(rand($Zcounts[$CIbinnum]));$rrtcodon = $Z[$CIbinnum][$random];}
					elsif ($codon eq "TGG"){$random = int(rand($Wcounts[$CIbinnum]));$rrtcodon = $W[$CIbinnum][$random];}
					elsif ($codon eq "CGT"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "CGC"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "CGA"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "CGG"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "AGA"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "AGG"){$random = int(rand($Rcounts[$CIbinnum]));$rrtcodon = $R[$CIbinnum][$random];}
					elsif ($codon eq "GGT"){$random = int(rand($Gcounts[$CIbinnum]));$rrtcodon = $G[$CIbinnum][$random];}
					elsif ($codon eq "GGC"){$random = int(rand($Gcounts[$CIbinnum]));$rrtcodon = $G[$CIbinnum][$random];}
					elsif ($codon eq "GGA"){$random = int(rand($Gcounts[$CIbinnum]));$rrtcodon = $G[$CIbinnum][$random];}
					elsif ($codon eq "GGG"){$random = int(rand($Gcounts[$CIbinnum]));$rrtcodon = $G[$CIbinnum][$random];}
					
					push(@curRRT,$rrtcodon);
					
					$cdnstart = $cdnstart + 3;
					
				}#until last codon: make current RRT
				
				++$attempts;++$totalattempts;
				
				
				$RRTseq = join('', @curRRT);
				$RRTprint = $RRTseq;
				
				#get overall %GC of last RRT made:
				$RRTseq =~ s/A//g;$RRTseq =~ s/T//g;
				$rrtGC = length $RRTseq;
				$prrtGC = 100*($rrtGC/$dnalength);
				$GCdif = $prrtGC - $perGC;
				$absGCdif = ($GCdif**2)**0.5;
				
				if ($absGCdif < $seqcutoff or $absGCdif == $seqcutoff){
					++$matched;
					print OUTPUT2 $header,"\n",$RRTprint,"\n";
					print OUTPUT "\t$seqcutoff\n";
				}#if close enough to original %GC content, print sequence
				
				else {
				
					if ($attempts == $trials){
						#if getting %GC too high: switch to bin with lower %GC content (unless already in lowest bin):
						if ($GCdif > 0){
							if ($CIbinnum - 1 > 0){$CIbinnum = $CIbinnum - 1;$attempts = 0;print OUTPUT  " to $CIbinnum";}
						}#current CI producing RRTs with %GC too high
						#if getting %GC too low: switch to bin with higher %GC content (unless already in highest bin):
						elsif ($GCdif < 0){
							if ($CIbinnum + 1 < $CIbins){$CIbinnum = $CIbinnum + 1;$attempts = 0;print OUTPUT  " to $CIbinnum";}
						}#current CI producing RRTs with %GC too low
					
					}#if not getting close %GC with current CI
				
					if ($totalattempts > $totaltrials){++$seqcutoff;$totalattempts = 0;}#if can't get an RRT within specified cutoff, increase cutoff
				
				}#else %GC not close enough
				
			}#until make a good RRT
			
			
		}#if full frame & no weird bases
		
		else {++$badgene;print OUTPUT "$header $codons codons and $lengthstuff unrecognized bases\n";}#else bad seq
	
	}#if starting new seq
}


close DNA;
exit;
